#include<iostream>
using namespace std;
//模板实例化：根据实参在编译阶段生成与实参匹配的函数或者是类

//隐式实例化
template<typename T>
T Add(const T& left,const T& right)
{
    return left + right;
}
int main()
{
    int a1 = 10,a2 = 20;
    Add(a1,a2);
    double d1 = 10.0,d2 = 20.0;
    //Add(d1,d2);
    //该语句不能通过编译
    //原因：在编译期间，进行模板的实例化，通过a1参数将T推演为int
    //                                     d1           double
    //无法确定将T确定为int或者是double类型而报错
    cout << Add<int>(a1,d1)<<'\n';
    return 0;
}

//对于解决上面的问题两种方式：1.用户自己来强制转换
//                          2.显示实例化


// int Add(int left, int right)
// {
// return left + right;
// }
// template<class T1, class T2>
// T1 Add(T1 left, T2 right)
// {
// return left + right;
// }
// void Test()
// {
// Add(1, 2);
// // 与非函数模板类型完全匹配，不需要函数模板实例化
// Add(1, 2.0);
// // 模板函数可以生成更加匹配的版本，编译器根据实参生成更加匹配的Add函数
// }
// int main()
// {
//     Test();
//     return 0;
// }


//函数匹配优先级：有匹配的普通函数，优先使用匹配的普通函数
//              无                      可以生产匹配函数的函数模板


//类的实例化
//vector 类名
//vector<int> ->实例化类型 


